package com.ms.pda.extensions

import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.databinding.BindingAdapter
import com.ms.pda.components.HeaderBar
import com.ms.pda.interf.SearchCallback
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.*

object ViewExt {

    @JvmStatic
    @BindingAdapter(value = ["bindTitle"])
    fun HeaderBar.bindTitle(title: String) {
        val titleTv = this.getChildAt(0) as TextView
        titleTv.text = title
    }

    @JvmStatic
    @BindingAdapter(value = ["imageRes"])
    fun ImageView.imageRes(res: Int) {
        this.setImageResource(res)
    }

    @JvmStatic
    @BindingAdapter("imageSelected")
    fun ImageView.imageSelected(selected: Boolean) {
        this.isSelected = selected
    }

    @JvmStatic
    @BindingAdapter(value = ["textSelected"])
    fun TextView.textSelected(selected: Boolean) {
        this.isSelected = selected
    }

    @JvmStatic
    @BindingAdapter(value = ["bindEnable"])
    fun View.bindEnable(enable: Boolean) {
        this.isEnabled = enable
    }

    private fun EditText.textChangedFlow(): Flow<String> = callbackFlow {
        val watcher = object : TextWatcher {
            override fun afterTextChanged(p0: Editable?) {
//                if (!StringUtils.isTrimEmpty(p0.toString()))
                trySend(p0.toString())
            }

            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }
        }

        addTextChangedListener(watcher)
        awaitClose { removeTextChangedListener(watcher) }
    }

    @JvmStatic
    @BindingAdapter(value = ["bindVisible"])
    fun View.bindVisible(visible: Boolean) {
        if (visible) {
            this.visibility = View.VISIBLE
        } else {
            this.visibility = View.GONE
        }
    }

    @ExperimentalCoroutinesApi
    @FlowPreview
    @JvmStatic
    @BindingAdapter(value = ["EditTextOnSearch"])
    fun EditText.onSearch(callback: SearchCallback) {
        this.textChangedFlow()
            .debounce(500)
            .flatMapLatest { flow { emit(it) } }
            .onEach { callback.onSearchChanged(this, it) }
            .launchIn(MainScope())
    }

    @JvmStatic
    @BindingAdapter(value = ["EditTextOnFocus"])
    fun EditText.onFocus(focus: View.OnFocusChangeListener) {
        this.onFocusChangeListener = focus
    }

    @JvmStatic
    @BindingAdapter(value = ["EditTextAction"])
    fun EditText.onAction(action: TextView.OnEditorActionListener) {
        this.setOnEditorActionListener(action)
    }

}